home *** CD-ROM | disk | FTP | other *** search
- /* SAP MAKER - Public Domain */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define word(l, h) ( ((h) << 8) | (l) )
- #define lo(x) ((x) & 0xff)
- #define hi(x) ((x) >> 8)
-
- char author[300];
- char name[300];
- char date[300];
- int songs;
- int defsong;
- enum {
- cmc = 0, cmr, mpt, md1, md2, tmc, tm8, ams, unknown
- } type;
- unsigned int music;
- unsigned int init;
- unsigned int player;
- char iname[300];
- char oname[300];
- FILE* ofile;
- unsigned char msx[63000];
- unsigned char* buf;
- unsigned char* smp;
- unsigned char* plr;
-
- /* Read file to buffer */
- void readfile(char* name, int offset) {
- FILE* tfile;
- if (!(tfile = fopen(name, "rb"))) {
- printf("Can't open %s\n", name);
- exit(2);
- }
- fseek(tfile, offset, SEEK_CUR);
- buf += fread(buf, 1, msx + sizeof(msx) - buf, tfile);
- fclose(tfile);
- }
-
- /* Create .SAP and write author,name,date,type */
- void saphdr(char t) {
- if (strlen(oname) > 30)
- printf("WARNING: File name \"%s\" longer than 30 characters\n", oname);
- if (!(ofile = fopen(oname, "wb"))) {
- printf("Can't create %s\n", oname);
- exit(2);
- }
- fprintf(ofile,
- "SAP\r\n"
- "AUTHOR %s\r\n"
- "NAME %s\r\n"
- "DATE %s\r\n"
- "TYPE %c\r\n",
- author, name, date, t);
- if (songs != 1) {
- fprintf(ofile, "SONGS %d\r\n", songs);
- if (defsong)
- fprintf(ofile, "DEFSONG %d\r\n", defsong);
- }
- }
-
- /* Procs for different music formats */
- void cmc_() {
- music = word(msx[2], msx[3]);
- player = (music >= 0x1000 ? 0x500 : 0xf500);
- readfile(type == cmr ? (player == 0x500 ? "cmr_0500.plr" : "cmr_f500.plr")
- : (player == 0x500 ? "cmc_0500.plr" : "cmc_f500.plr")
- , 2);
- saphdr('C');
- fprintf(ofile,
- "MUSIC %04X\r\n"
- "PLAYER %04X\r\n",
- music, player);
- }
-
- void mpt_() {
- player = (msx[3] >= '\x10' ? 0x500 : 0xf500);
- /* dta a(begin,end)
- ; = 4 bytes
- ldy #<msx
- ldx #>msx
- lda #0
- jsr player
- ldx #0 ;song pos
- lda #2
- ; = 13 bytes
- player jmp init
- jmp play
- */
- plr = buf;
- buf += 17;
- readfile(player == 0x500 ? "mpt_0500.plr" : "mpt_f500.plr", 6);
- plr[0] = lo(player - 13); plr[1] = hi(player - 13);
- plr[2] = lo(player - 16 + buf - plr); plr[3] = hi(player - 16 + buf - plr);
- plr[4] = '\xa0'; plr[5] = msx[2];
- plr[6] = '\xa2'; plr[7] = msx[3];
- plr[8] = '\xa9'; plr[9] = '\x00';
- plr[10] = '\x20'; plr[11] = lo(player); plr[12] = hi(player);
- plr[13] = '\xa2'; plr[14] = '\x00';
- plr[15] = '\xa9'; plr[16] = '\x02';
- saphdr('B');
- fprintf(ofile,
- "INIT %04X\r\n"
- "PLAYER %04X\r\n",
- player - 13, player + 3);
- }
-
- void readSamples(char* ext) {
- smp = buf;
- buf += 4;
- strcpy(strrchr(iname, '.') + 1, ext);
- readfile(iname, 0);
- smp[0] = '\xe0';
- smp[1] = smp[4] - 1;
- smp[2] = '\xff';
- smp[3] = smp[4] + hi(buf - smp - 0x25);
- if (!(msx[5] < smp[1] || msx[3] > smp[3])) {
- int i = hi(buf - smp - 0x25);
- int h = 0x0e + i < msx[3] ? 0x0e : 0xcf - i;
- printf("WARNING: Conflict between music and samples %s. Placing samples at $%02X00.\n", iname, h);
- h -= smp[4];
- smp[1] += h;
- smp[3] += h;
- for (i = 0; i < 0x20; i++)
- if (smp[4 + i])
- smp[4 + i] += h;
- }
-
- player = (msx[3] >= '\x10' && smp[4] >= '\x10' ? 0x500 : 0xf500);
- }
-
- void md1_() {
- FILE *tfile;
- unsigned char is15kHz;
- /* Check if there are .D15 samples */
- strcpy(strrchr(iname, '.') + 1, "d15");
- tfile = fopen(iname, "rb");
- if (tfile != NULL) {
- fclose(tfile);
- /* Read .D15 samples */
- readSamples("d15");
- is15kHz = 1;
- }
- else {
- /* Read .D8 samples */
- readSamples("d8");
- is15kHz = 0;
- }
- /* dta a(begin,end)
- ; = 4 bytes
- ldy #<msx
- ldx #>msx
- lda #0
- jsr player
- ldy #<smp
- ldx #>smp
- lda #3
- jsr player
- ldx #0 ;song pos
- lda #2
- jsr player
- ldx #1 ;0=7.5kHz 1=15kHz
- lda #5
- ; = 29 bytes
- player jmp init
- jmp play
- */
- plr = buf;
- buf += 33;
- readfile(player == 0x500 ? "mpt_0500.plr" : "mpt_f500.plr", 6);
- plr[0] = lo(player - 29); plr[1] = hi(player - 29);
- plr[2] = lo(player - 32 + buf - plr); plr[3] = hi(player - 32 + buf - plr);
- plr[4] = '\xa0'; plr[5] = msx[2];
- plr[6] = '\xa2'; plr[7] = msx[3];
- plr[8] = '\xa9'; plr[9] = '\x00';
- plr[10] = '\x20'; plr[11] = lo(player); plr[12] = hi(player);
- plr[13] = '\xa0'; plr[14] = '\xe0';
- plr[15] = '\xa2'; plr[16] = smp[4] - 1;
- plr[17] = '\xa9'; plr[18] = '\x03';
- plr[19] = '\x20'; plr[20] = lo(player); plr[21] = hi(player);
- plr[22] = '\xa2'; plr[23] = '\x00';
- plr[24] = '\xa9'; plr[25] = '\x02';
- plr[26] = '\x20'; plr[27] = lo(player); plr[28] = hi(player);
- plr[29] = '\xa2'; plr[30] = is15kHz;
- plr[31] = '\xa9'; plr[32] = '\x05';
- saphdr('D');
- fprintf(ofile,
- "INIT %04X\r\n"
- "PLAYER %04X\r\n",
- player - 29, player + 3);
- }
-
- void md2_() {
- /* Read .D8 samples */
- readSamples("d8");
- /* dta a(begin,end)
- ; = 4 bytes
- ldy #<msx
- ldx #>msx
- lda #0
- jsr player
- ldy #<smp
- ldx #>smp
- lda #3
- jsr player
- ldx #0 ;song pos
- lda #2
- jsr player
- lda #6
- ; = 27 bytes
- */
- plr = buf;
- buf += 31;
- readfile(player == 0x500 ? "mpt_0500.plr" : "mpt_f500.plr", 6);
- plr[0] = lo(player - 27); plr[1] = hi(player - 27);
- plr[2] = lo(player - 30 + buf - plr); plr[3] = hi(player - 30 + buf - plr);
- plr[4] = '\xa0'; plr[5] = msx[2];
- plr[6] = '\xa2'; plr[7] = msx[3];
- plr[8] = '\xa9'; plr[9] = '\x00';
- plr[10] = '\x20'; plr[11] = lo(player); plr[12] = hi(player);
- plr[13] = '\xa0'; plr[14] = '\xe0';
- plr[15] = '\xa2'; plr[16] = smp[4] - 1;
- plr[17] = '\xa9'; plr[18] = '\x03';
- plr[19] = '\x20'; plr[20] = lo(player); plr[21] = hi(player);
- plr[22] = '\xa2'; plr[23] = '\x00';
- plr[24] = '\xa9'; plr[25] = '\x02';
- plr[26] = '\x20'; plr[27] = lo(player); plr[28] = hi(player);
- plr[29] = '\xa9'; plr[30] = '\x06';
- saphdr('D');
- fprintf(ofile,
- "INIT %04X\r\n"
- "PLAYER %04X\r\n",
- player - 27, player + 3);
- }
-
- void tmc_() {
- int len;
-
- player = (msx[3] >= '\x10' ? 0x500 : 0xf500);
- /* dta a(begin,end)
- ; = 4 bytes
- ldy #<msx
- ldx #>msx
- lda #$70
- jsr player
- lda #$60
- ; = 11 bytes
- ; 1/frame
- ; = 0 bytes
- player jmp init
- jmp play
- jmp sound
- ; 2/frame - FASTPLAY 156
- asl 0
- jmp player
- play lda 0
- inc 0
- lsr @
- bcc player+3
- bcs player+6 !
- ; = 14 bytes
- player
- ; 3/frame - FASTPLAY 104
- ldx #1
- stx 0
- bne player !
- play dec 0
- bne player+6
- ldx #3
- stx 0
- bne player+3 !
- ; = 16 bytes
- player
- ; 4/frame - FASTPLAY 78
- ldx #1
- stx 0
- bne player !
- play dec 0
- bne player+6
- ldx #4
- stx 0
- bne player+3 !
- ; = 16 bytes
- player
- */
- plr = buf;
- len = " \x0b\x19\x1b\x1b"[msx[37]];
- buf += 4 + len;
- readfile(player == 0x500 ? "tmc_0500.plr" : "tmc_f500.plr", 6);
- init = player - len;
- plr[0] = lo(init); plr[1]=hi(init);
- plr[2] = lo(init - 5 + buf - plr); plr[3]=hi(init - 5 + buf - plr);
- plr[4] = '\xa0'; plr[5] = msx[2];
- plr[6] = '\xa2'; plr[7] = msx[3];
- plr[8] = '\xa9'; plr[9] = '\x70';
- plr[10] = '\x20'; plr[11] = lo(player); plr[12] = hi(player);
- plr[13] = '\xa9'; plr[14] = '\x60';
- switch (msx[37]) {
- case '\4':
- case '\3':
- plr[15] = '\xa2'; plr[16] = '\x01';
- plr[17] = '\x86'; plr[18] = '\x00';
- plr[19] = '\xd0'; plr[20] = '\x0a';
- player -= 10;
- plr[21] = '\xc6'; plr[22] = '\x00';
- plr[23] = '\xd0'; plr[24] = '\x0c';
- plr[25] = '\xa2'; plr[26] = msx[37];
- plr[27] = '\x86'; plr[28] = '\x00';
- plr[29] = '\xd0'; plr[30] = '\x03';
- break;
- case '\2':
- plr[15] = '\x06'; plr[16] = '\x00';
- plr[17] = '\x4c'; plr[18] = lo(player); plr[19] = hi(player);
- player -= 9;
- plr[20] = '\xa5'; plr[21] = '\x00';
- plr[22] = '\xe6'; plr[23] = '\x00';
- plr[24] = '\x4a';
- plr[25] = '\x90'; plr[26] = '\x05';
- plr[27] = '\xb0'; plr[28] = '\x06';
- break;
- case '\1':
- player += 3;
- break;
- }
- saphdr('B');
- if (type == tm8)
- fprintf(ofile, "STEREO\r\n");
- if (msx[37] > 1)
- fprintf(ofile, "FASTPLAY %d\r\n", ((unsigned char *) " \x9c\x68\x4e")[msx[37]]);
- fprintf(ofile,
- "INIT %04X\r\n"
- "PLAYER %04X\r\n",
- init, player);
- }
-
- int convasc(unsigned char **pp)
- {
- int r = 0;
- unsigned char *p = *pp;
- while (*p == ' ')
- p++;
- while (*p != 0x9b) {
- if (*p == '.') {
- while (*++p != 0x9b);
- break;
- }
- r *= 10;
- r += *p - '0';
- p++;
- }
- *pp = p + 1;
- return r;
- }
-
- void ams_() {
- int i;
- unsigned char *p = msx;
- unsigned int v[4];
- unsigned int len = 0;
- unsigned int m;
- int time;
- for (i = 0; i < 4; i++) {
- len += convasc(&p);
- v[i] = convasc(&p);
- }
- time = convasc(&p);
- convasc(&p);
- time = (385091 / time - 639) / 5.0234375;
- p += len;
- len = 2 * v[3];
- memmove(msx + sizeof(msx) - len, p, len);
-
- buf = msx;
- readfile("ams_0500.plr", 0);
- m = word(msx[28], msx[29]) + 1;
- p = msx + 6;
- *p++ = lo(time); *p++ = hi(time);
- *p++ = lo(m); *p++ = hi(m);
- *p++ = lo(m + v[0]); *p++ = hi(m + v[0]);
- *p++ = lo(m + v[1]); *p++ = hi(m + v[1]);
- *p++ = lo(m + v[2]); *p++ = hi(m + v[2]);
- *p++ = lo(m + v[3]); *p++ = hi(m + v[3]);
- *p++ = lo(m + v[3] + v[0]); *p++ = hi(m + v[3] + v[0]);
- *p++ = lo(m + v[3] + v[1]); *p++ = hi(m + v[3] + v[1]);
- *p++ = lo(m + v[3] + v[2]); *p++ = hi(m + v[3] + v[2]);
- *p++ = lo(m + v[3] + v[3]); *p++ = hi(m + v[3] + v[3]);
- msx[28] = lo(m + len - 1); msx[29] = hi(m + len - 1);
- memmove(buf, msx + sizeof(msx) - len, len);
- buf += len;
- saphdr('D');
- fprintf(ofile,
- "INIT 0500\r\n"
- "PLAYER 0503\r\n");
- }
-
- int main(int argc, char** argv) {
- char* exts[] = {"cmc", "cmr", "mpt", "md1", "md2", "tmc", "tm8", "ams"};
- void (*procs[])() = {cmc_, cmc_, mpt_, md1_, md2_, tmc_, tmc_, ams_};
- FILE* ifile;
- char line[1000];
- int i;
- char* p;
- char* q;
- char* t[6];
- unsigned endad;
-
- if (argc != 2) {
- printf("SAP Maker v4 by Piotr Fusik/Fox/Taquart (fox@scene.pl) [070202]\n");
- printf("Amiga port by Wojciech Pasiecznik/Voy/SSG/Dial (voydial@wp.pl)\n\n");
- puts("Give info file name");
- return 3;
- }
- if (!(ifile = fopen(argv[1], "r"))) {
- printf("Can't open %s\n", argv[1]);
- return 3;
- }
- while (!feof(ifile)) {
- /* Get input and output names, songs, defsong */
- fgets(line, sizeof(line), ifile);
- if (feof(ifile))
- break;
- if (*line == ';' || *line == '\n')
- continue;
- switch (sscanf(line, "%s %s %d %d", iname, oname, &songs, &defsong)) {
- case 0:
- printf("Invalid line %s\n", line);
- fclose(ifile);
- return 2;
- case 1:
- sprintf(oname, "%.*s.sap", strrchr(iname, '.') - iname, iname);
- case 2:
- songs = 1;
- case 3:
- defsong = 0;
- default:
- break;
- }
- /* Recognize extension */
- p = strrchr(iname, '.') + 1;
- for (type = cmc; type < unknown; type++)
- if (stricmp(p, exts[type]) == 0)
- break;
- if (type == unknown) {
- printf("Unknown type of %s\n", iname);
- return 2;
- }
- /* Read music */
- buf = msx;
- readfile(iname, 0);
- if (type != ams) {
- if (msx[0] != 0xff || msx[1] != 0xff) {
- printf("%s is not valid music file\n", iname);
- return 2;
- }
- endad = word(msx[2], msx[3]) + buf - msx - 7;
- if (endad != word(msx[4], msx[5]) ) {
- printf("WARNING: Fixing invalid header of %s\n", iname);
- msx[4] = lo(endad);
- msx[5] = hi(endad);
- }
- }
- /* Get author, name and date */
- /* Defaults: "<?>", "sap name", "<?>" */
- strcpy(author, "\"<?>\"");
- for(p = oname, q = name + 1; *p != '.'; p++, q++)
- *q = (*p == '_' ? ' ' : *p);
- *name = *q++ = '"';
- *q = '\0';
- strcpy(date, "\"<?>\"");
- /* Find '"' */
- p = line;
- for (i = 0; i < 6; i++)
- if(!(t[i] = p = strchr(p + 1, '"')))
- break;
- /* Set author, name and date if given */
- switch (i) {
- case 6:
- t[5][1] = '\0';
- strcpy(date, t[4]);
- case 5:
- case 4:
- t[3][1] = '\0';
- strcpy(name, t[2]);
- case 3:
- case 2:
- t[1][1] = '\0';
- strcpy(author, t[0]);
- default:
- break;
- }
- /* Run proper procedure */
- procs[type]();
- /* Write binary part */
- fwrite(msx, buf - msx, 1, ofile);
- /* Close file */
- fclose(ofile);
- }
- fclose(ifile);
- return 0;
- }
-